package com.dongnam.quanly.web.danhmuc.loaivthh;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import jxl.Cell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.format.Alignment;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.TreeNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dongnam.quanly.common.controller.LoaiVatTuHangHoaController;
import com.dongnam.quanly.common.exceptions.DatabaseException;
import com.dongnam.quanly.common.model.KhoHang;
import com.dongnam.quanly.common.model.LoaiVatTuHangHoa;
import com.dongnam.quanly.common.model.NhomDoiTac;
import com.dongnam.quanly.web.UserBean;
import com.dongnam.quanly.web.util.CsvUtil;
import com.dongnam.quanly.web.util.WebUtil;

@ManagedBean(name = "LoaiVTHHBean")
@SessionScoped
public class LoaiVTHHBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static final Logger logger = LoggerFactory.getLogger(LoaiVTHHBean.class);

	@ManagedProperty(value = "#{UserBean}")
	private UserBean userBean;
	private TreeNode loaivthhRoot;
	private TreeNode selectedNode;
	private boolean flag = false;

	// for add loaiVTHH
	private String maloaivthh;
	private String tenloaivthh;
	private String thuocloaivthh;
	private String diengiai;
	private boolean edit = false;

	// for download file
	private StreamedContent file;

	// for load danh sach phong ban
	private LoaiVatTuHangHoaController loaiVTHHController;
	private List<LoaiVatTuHangHoa> listloaivthh;

	// for edit loaiVTHH
	private LoaiVatTuHangHoa selectedloaivthh;

	public LoaiVTHHBean() {
		// TODO Auto-generated constructor stub
	}

	public LoaiVatTuHangHoaController getloaiVTHHController() {

		if (loaiVTHHController == null)
			loaiVTHHController = new LoaiVatTuHangHoaController();
		return loaiVTHHController;
	}

	public void downloadFileCSV() {

		File excelfile = new File("LOAI_VAT_TU_HANG_HOA.xls");
		List<LoaiVatTuHangHoa> list = getloaiVTHHController().findAll();
		int length = list.size();
		try {
			WritableWorkbook workbook = Workbook.createWorkbook(excelfile);
			WritableSheet sheet = workbook.createSheet("First Sheet", 0);

			// style for title
			WritableFont titlefont = new WritableFont(WritableFont.ARIAL, 16, WritableFont.BOLD);
			WritableCellFormat titleformat = new WritableCellFormat(titlefont);
			titleformat.setAlignment(Alignment.LEFT);
			titleformat.setWrap(false);

			// style for content
			WritableFont contentfont = new WritableFont(WritableFont.ARIAL, 13);
			WritableCellFormat contentformat = new WritableCellFormat(contentfont);
			contentformat.setAlignment(Alignment.LEFT);
			contentformat.setWrap(false);

			// thiet lap tieu de
			sheet.setColumnView(0, 30);
			sheet.setColumnView(1, 30);
			sheet.setColumnView(2, 30);
			sheet.setColumnView(3, 30);

			sheet.addCell(new Label(0, 0, "Mã Loại", titleformat));
			sheet.addCell(new Label(1, 0, "Tên Loại", titleformat));
			sheet.addCell(new Label(2, 0, "Thuộc Loại", titleformat));
			sheet.addCell(new Label(3, 0, "Diễn Giải", titleformat));

			for (int i = 0; i < length; i++) {

				sheet.addCell(new Label(0, i + 1, list.get(i).getMaLoai(), contentformat));
				sheet.addCell(new Label(1, i + 1, list.get(i).getTenLoai(), contentformat));
				sheet.addCell(new Label(2, i + 1, list.get(i).getThuocLoai(), contentformat));
				sheet.addCell(new Label(3, i + 1, list.get(i).getDienGiai(), contentformat));

			}

			workbook.write();
			workbook.close();

			file = new DefaultStreamedContent(new FileInputStream(excelfile), "application/csv",
					"LOAI_VAT_TU_HANG_HOA.xls", "UTF-8");

		} catch (IOException | WriteException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

	}

	public boolean isEdit() {
		return edit;
	}

	public void setEdit(boolean edit) {
		this.edit = edit;
	}

	public void handleFileUpload(FileUploadEvent event) {

		logger.debug("process upload file ");
		Workbook w;
		boolean rollback = false;
		List<LoaiVatTuHangHoa> list = new ArrayList<LoaiVatTuHangHoa>();
		try {
			w = Workbook.getWorkbook(event.getFile().getInputstream());
			// Get the first sheet
			Sheet sheet = w.getSheet(0);
			// Loop over first 10 column and lines

			for (int row = 1; row < sheet.getRows(); row++) {

				Cell cell_ma_ndt = sheet.getCell(0, row);
				Cell cell_ten_ndt = sheet.getCell(1, row);
				Cell cell_thuoc_ndt = sheet.getCell(2, row);
				Cell cell_dienGiai = sheet.getCell(3, row);

				LoaiVatTuHangHoa lvthh = new LoaiVatTuHangHoa();
				lvthh.setMaLoai(cell_ma_ndt.getContents());
				lvthh.setTenLoai(cell_ten_ndt.getContents());
				lvthh.setThuocLoai(cell_thuoc_ndt.getContents());
				lvthh.setDienGiai(cell_dienGiai.getContents());
				boolean isHasChild = false;
				for (int i = 0; i < sheet.getRows(); i++) {
					Cell cell_thuoc_ndt_test = sheet.getCell(2, i);
					if (cell_ma_ndt.getContents().equals(cell_thuoc_ndt_test.getContents())) {
						isHasChild = true;
						break;
					}
				}
				lvthh.setIsHasChild(isHasChild);
				list.add(lvthh);
			}
		} catch (BiffException | IOException e) {
			e.printStackTrace();
			rollback = true;
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful : Database error : "
					+ e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

		if (!rollback) {
			getloaiVTHHController().batchSaveOrUpdate(list);
		}

		loadloaiVTHH();
	}

	public void resetFormAdd() {
		maloaivthh = null;
		tenloaivthh = null;
		thuocloaivthh = null;
		diengiai = null;
	}

	public void notifyAdd() {
		edit = false;
		resetFormAdd();
		listloaivthh = getloaiVTHHController().findAll();
	}

	public void findNote(TreeNode root, LoaiVatTuHangHoa loaiVatTuHangHoa) {

		if (!flag) {
			if (root.isLeaf()) {

				if (((LoaiVatTuHangHoa) root.getData()).getMaLoai().equals(loaiVatTuHangHoa.getMaLoai())) {
					flag = true;
					this.selectedNode = root;
				}
			}

			else {

				if (root.getData() != null) {
					if (((LoaiVatTuHangHoa) root.getData()).getMaLoai().equals(loaiVatTuHangHoa.getMaLoai())) {
						flag = true;
						this.selectedNode = root;
					} else {
						List<TreeNode> listnode = root.getChildren();
						int length = listnode.size();
						for (int i = 0; i < length; i++) {
							findNote(listnode.get(i), loaiVatTuHangHoa);
						}
					}
				} else {
					List<TreeNode> listnode = root.getChildren();
					int length = listnode.size();
					for (int i = 0; i < length; i++) {
						findNote(listnode.get(i), loaiVatTuHangHoa);
					}
				}

			}
		}
	}

	public void notifyEdit(LoaiVatTuHangHoa loaiVTHH) {
		edit = true;
		this.selectedloaivthh = loaiVTHH;
		maloaivthh = this.selectedloaivthh.getMaLoai();
		tenloaivthh = this.selectedloaivthh.getTenLoai();
		thuocloaivthh = this.selectedloaivthh.getThuocLoai();
		diengiai = this.selectedloaivthh.getDienGiai();
		List<String> listtest = new ArrayList<String>();

		this.flag = false;
		this.selectedNode = null;
		findNote(this.loaivthhRoot, loaiVTHH);
		if (this.selectedNode != null)

			deepTree(this.selectedNode, listtest);

		for (int i = 0; i < listtest.size(); i++) {
			logger.info(listtest.get(i) + "hsadb");
		}

		if (listtest.size() != 0)
			listloaivthh = getloaiVTHHController().listLoaiVatTuHangHoaExclude(listtest);
		else
			listloaivthh = getloaiVTHHController().findAll();
	}

	public void deepTree(TreeNode root, List<String> list) {
		if (root.isLeaf()) {
			logger.info("Name " + ((LoaiVatTuHangHoa) root.getData()).getMaLoai());
			list.add(((LoaiVatTuHangHoa) root.getData()).getMaLoai());
		} else {
			logger.info("Name " + ((LoaiVatTuHangHoa) root.getData()).getMaLoai());
			list.add(((LoaiVatTuHangHoa) root.getData()).getMaLoai());
			List<TreeNode> listnode = root.getChildren();
			int length = listnode.size();
			for (int i = 0; i < length; i++) {
				deepTree(listnode.get(i), list);
			}
		}
	}

	public void removeloaivthh() {

		if (this.selectedloaivthh != null) {
			getloaiVTHHController().makeTransient(this.selectedloaivthh);

			List<String> listtest = new ArrayList<String>();

			this.flag = false;
			this.selectedNode = null;
			findNote(this.loaivthhRoot, this.selectedloaivthh);
			if (this.selectedNode != null)

				deepTree(this.selectedNode, listtest);

			for (int i = 0; i < listtest.size(); i++) {
				logger.info(listtest.get(i) + "hsadb");
			}

			getloaiVTHHController().batchDelete(getloaiVTHHController().listLoaiVatTuHangHoaInclude(listtest));
			loadloaiVTHH();
			;
			listloaivthh = getloaiVTHHController().findAll();
		}

	}

	public List<LoaiVatTuHangHoa> findListByParent(String parentID) {
		LoaiVatTuHangHoa exam = new LoaiVatTuHangHoa();
		exam.setThuocLoai(parentID);
		return getloaiVTHHController().findByExample(exam);

	}

	private void setParent() {
		if (!this.thuocloaivthh.equals("root")) {
			LoaiVatTuHangHoa pbparent = getloaiVTHHController().findById(this.thuocloaivthh, false);
			if (pbparent != null) {
				logger.debug("Phong Ban parent: " + pbparent.getMaLoai());
				pbparent.setIsHasChild(Boolean.TRUE);
				getloaiVTHHController().makePersistent(pbparent);
			}
		}
	}

	public void save() {

		RequestContext context = RequestContext.getCurrentInstance();
		try {
			if (edit) {

				if (this.selectedloaivthh != null) {

					logger.debug("Edit new loaiVTHH");

					// getloaiVTHHController().makeTransient(this.selectedloaivthh);

					this.selectedloaivthh.setUpdateBy(userBean.getUser().getUserId());
					this.selectedloaivthh.setMaLoai(this.maloaivthh);
					this.selectedloaivthh.setTenLoai(this.tenloaivthh);
					this.selectedloaivthh.setThuocLoai(this.thuocloaivthh);
					this.selectedloaivthh.setDienGiai(this.diengiai);

					getloaiVTHHController().makePersistent(this.selectedloaivthh);
					// change state of parent
					setParent();
					context.addCallbackParam("opSuccess", true);
				}

			} else {

				logger.debug("Add new loaiVTHH");
				LoaiVatTuHangHoa pb = new LoaiVatTuHangHoa();
				pb.setCreateBy(userBean.getUser().getUserId());
				pb.setUpdateBy(userBean.getUser().getUserId());

				pb.setMaLoai(this.maloaivthh);
				pb.setTenLoai(this.tenloaivthh);
				pb.setThuocLoai(this.thuocloaivthh);
				pb.setDienGiai(this.diengiai);
				pb.setIsHasChild(Boolean.FALSE);

				getloaiVTHHController().makePersistent(pb);

				// change state of parent
				if (!this.thuocloaivthh.equals("root")) {
					setParent();
				}

				listloaivthh = getloaiVTHHController().findAll();
				context.addCallbackParam("opSuccess", true);

			}
		} catch (DatabaseException e) {
			e.printStackTrace();
			logger.debug("Database error" + e.getMessage());
			context.addCallbackParam("opSuccess", false);

			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Unsuccessful : Database error : "
					+ e.getMessage(), "");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}

		loadloaiVTHH();

	}

	public void loadloaiVTHH() {
		if (loaivthhRoot == null)
			loaivthhRoot = new DefaultTreeNode();

		loaivthhRoot.getChildren().clear();

		List<LoaiVatTuHangHoa> listgroup = loadParents();
		List<LoaiVatTuHangHoa> listchild = loadChilds();
		createListloaiVTHH("root", loaivthhRoot, listgroup, listchild, listgroup.size(), listchild.size());
		this.loaivthhRoot.setExpanded(true);
	}

	private List<LoaiVatTuHangHoa> loadChilds() {
		LoaiVatTuHangHoa exam = new LoaiVatTuHangHoa();
		exam.setIsHasChild(Boolean.FALSE);
		return getloaiVTHHController().findByExample(exam);
	}

	private List<LoaiVatTuHangHoa> loadParents() {
		LoaiVatTuHangHoa exam = new LoaiVatTuHangHoa();
		exam.setIsHasChild(Boolean.TRUE);
		return getloaiVTHHController().findByExample(exam);

	}

	public void createListloaiVTHH(String parentID, TreeNode parent, List<LoaiVatTuHangHoa> listgroups,
			List<LoaiVatTuHangHoa> listloaiVTHH, int lengthgroups, int lenghtloaiVTHH) {

		for (int i = 0; i < lengthgroups; i++) {
			if (listgroups.get(i).getThuocLoai().equals(parentID)) {
				TreeNode group = new DefaultTreeNode(listgroups.get(i), parent);
				createListloaiVTHH(listgroups.get(i).getMaLoai(), group, listgroups, listloaiVTHH, lengthgroups,
						lenghtloaiVTHH);
			}
		}

		for (int j = 0; j < lenghtloaiVTHH; j++) {

			if (listloaiVTHH.get(j).getThuocLoai().equals(parentID)) {
				new DefaultTreeNode(listloaiVTHH.get(j), parent);
			}
		}
	}

	public StreamedContent getFile() {
		return file;
	}

	public void setFile(StreamedContent file) {
		this.file = file;
	}

	public UserBean getUserBean() {
		return userBean;
	}

	public void setUserBean(UserBean userBean) {
		this.userBean = userBean;
	}

	public String getDiengiai() {
		return diengiai;
	}

	public void setDiengiai(String diengiai) {
		this.diengiai = diengiai;
	}

	public List<LoaiVatTuHangHoa> getListloaivthh() {

		if (listloaivthh == null)
			listloaivthh = getloaiVTHHController().findAll();

		return listloaivthh;
	}

	public void setListloaivthh(List<LoaiVatTuHangHoa> listloaivthh) {
		this.listloaivthh = listloaivthh;
	}

	public TreeNode getLoaivthhRoot() {
		return loaivthhRoot;
	}

	public void setLoaivthhRoot(TreeNode loaivthhRoot) {
		this.loaivthhRoot = loaivthhRoot;
	}

	public LoaiVatTuHangHoa getSelectedloaivthh() {
		return selectedloaivthh;
	}

	public void setSelectedloaivthh(LoaiVatTuHangHoa selectedloaivthh) {
		this.selectedloaivthh = selectedloaivthh;
	}

	public void reloadPage() {
		listloaivthh = getloaiVTHHController().findAll();
		loadloaiVTHH();
		WebUtil.redirect("/pages/danhmuc/loaiVatTuHangHoa.xhtml");
	}

	public String getMaloaivthh() {
		return maloaivthh;
	}

	public void setMaloaivthh(String maloaivthh) {
		this.maloaivthh = maloaivthh;
	}

	public String getTenloaivthh() {
		return tenloaivthh;
	}

	public void setTenloaivthh(String tenloaivthh) {
		this.tenloaivthh = tenloaivthh;
	}

	public String getThuocloaivthh() {
		return thuocloaivthh;
	}

	public void setThuocloaivthh(String thuocloaivthh) {
		this.thuocloaivthh = thuocloaivthh;
	}

}
